import React, {useCallback, useMemo} from 'react';
import {Edit, GripVertical, MoreHorizontal, Plus, Trash2} from 'lucide-react';
import {closestCenter, DndContext, DragEndEvent, DragOverlay, DragStartEvent} from '@dnd-kit/core';
import {arrayMove, SortableContext, useSortable, verticalListSortingStrategy} from '@dnd-kit/sortable';
import {CSS} from '@dnd-kit/utilities';
import * as RadixPopover from '@radix-ui/react-popover';
import {SpaceModal} from '@/components/modals/SpaceModal';
import {SpaceIcon} from '@/components/ui/SpaceIcon';
import {ScrollContainer} from '@/components/ui/ScrollContainer';
import {Tooltip} from '@/components/ui/Tooltip';
import {IconButton} from '@/components/ui/Button';
import {useActiveSpaceStore} from '@/stores/activeSpace';
import {ConfirmModal} from '@/components/modals/Modal';
import {useToast} from '@/hooks/ui';
import {calculateDragPositionUpdates, cn} from '@/lib/utils';
import type {Space} from '@/types';
// 导入 TanStack Query hooks
import {useDeleteSpace, useReorderSpaces, useSpaces} from '@/hooks/api';
import {useQueryClient} from '@tanstack/react-query';
import {QueryKeys} from '@/lib/queryClient';

/**
 * 可拖拽的空间项组件
 * 功能：拖拽排序、状态管理、操作按钮
 */
interface SortableSpaceItemProps {
    // 空间数据
    space: Space;
    // 是否为活跃空间
    isActive: boolean;
    // 点击空间的回调
    onSpaceClick: (spaceId: number) => void;
    // 编辑空间的回调
    onEditSpace: (space: Space, e: React.MouseEvent) => void;
    // 删除空间的回调
    onDeleteSpace: (space: Space) => void;
}

const SortableSpaceItemComponent: React.FC<SortableSpaceItemProps> = ({
    space,
    isActive,
    onSpaceClick,
    onEditSpace,
    onDeleteSpace
}) => {
    const [isMenuOpen, setIsMenuOpen] = React.useState(false);
    const [isHovered, setIsHovered] = React.useState(false);

    // 拖拽相关hooks
    // 禁用 animateLayoutChanges 避免数据更新时的二次动画
    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging
    } = useSortable({
        id: space.id,
        animateLayoutChanges: () => false // 禁用自动布局动画
    });

    // 处理空间点击事件 - 恢复原有简单逻辑
    const handleSpaceClick = React.useCallback((e: React.MouseEvent) => {
        // 如果点击的是拖拽手柄或菜单按钮区域，不处理空间点击
        if ((e.target as HTMLElement).closest('[data-drag-handle]') ||
            (e.target as HTMLElement).closest('[data-menu-trigger]')) {
            return;
        }
        onSpaceClick(space.id);
    }, [onSpaceClick, space.id]);

    // 处理鼠标进入 - 显示拖拽手柄
    const handleMouseEnter = React.useCallback(() => {
        setIsHovered(true);
    }, []);

    // 处理鼠标离开 - 隐藏拖拽手柄
    const handleMouseLeave = React.useCallback(() => {
        setIsHovered(false);
    }, []);

    // 处理编辑操作
    const handleEdit = React.useCallback((e: React.MouseEvent) => {
        e.stopPropagation();
        setIsMenuOpen(false);
        onEditSpace(space, e);
        setIsHovered(false);
    }, [onEditSpace, space]);

    // 处理删除操作
    const handleDelete = React.useCallback((e: React.MouseEvent) => {
        e.stopPropagation();
        setIsMenuOpen(false);
        onDeleteSpace(space);
        setIsHovered(false);
    }, [onDeleteSpace, space]);

    // 拖拽样式
    const style = {
        transform: CSS.Transform.toString(transform),
        transition,
    };

    return (
        <div
            ref={setNodeRef}
            style={style}
            // Hover交互事件
            onClick={handleSpaceClick}
            onMouseEnter={handleMouseEnter}
            onMouseLeave={handleMouseLeave}
            className={cn(
                'relative flex items-center gap-2.5 pl-4 pr-3 py-2 text-sm cursor-pointer',
                ' transition-colors w-full min-w-0 group select-none rounded-xl',
                isActive
                    ? 'text-gray-800 bg-gray-100 hover:bg-gray-50 font-medium'
                    : 'text-gray-500 hover:text-gray-700 hover:bg-gray-50',
                isDragging && 'opacity-50 scale-105 z-50'
            )}
            {...attributes}
        >
            {/* 左侧图标区域 - Hover时切换为拖拽手柄 */}
            <div className="flex-shrink-0 relative">
                {/* 默认状态：显示空间图标 */}
                <SpaceIcon
                    iconId={space.icon}
                    size={16}
                    className={cn(
                        'text-current',
                        isHovered && 'opacity-0'
                    )}
                    color={space.icon_color}
                />
                {/* Hover状态：显示拖拽手柄 - 使用Tooltip组件 */}
                <div
                    data-drag-handle
                    {...listeners}
                    className={cn(
                        'absolute inset-0 flex items-center justify-center',
                        'opacity-0 pointer-events-none',
                        isHovered && 'opacity-100 pointer-events-auto'
                    )}
                >
                    <Tooltip
                        content="排序"
                        side="bottom"
                        variant="edit"
                    >
                        <IconButton
                            variant="ghost"
                            size="sm"
                            icon={<GripVertical size={16}/>}
                            className={cn(
                                'w-6 h-6 p-1 cursor-grab hover:bg-gray-300',
                                isDragging && 'cursor-grabbing bg-blue-100'
                            )}
                            style={{color: space.icon_color}}
                            // 阻止IconButton的默认点击行为，保持纯拖拽功能
                            onClick={(e) => e.preventDefault()}
                        />
                    </Tooltip>
                </div>
            </div>

            {/* 空间名称 */}
            <span className="truncate flex-1">{space.name}</span>

            {/* 右侧操作区域 - 仅显示操作菜单 */}
            <div className="flex items-center opacity-0 group-hover:opacity-100 transition-opacity">
                {/* 操作菜单按钮 */}
                <RadixPopover.Root open={isMenuOpen} onOpenChange={setIsMenuOpen}>
                    <Tooltip
                        content="操作"
                        side="right"
                        variant="edit"
                    >
                        <RadixPopover.Trigger asChild>
                            <IconButton
                                data-menu-trigger
                                variant="ghost"
                                size="sm"
                                icon={<MoreHorizontal size={14}/>}
                                onClick={(e) => e.stopPropagation()}
                                className="flex-shrink-0 w-6 h-6 p-1 hover:bg-gray-200"
                                style={{color: space.icon_color}}
                            />
                        </RadixPopover.Trigger>
                    </Tooltip>

                    <RadixPopover.Portal>
                        <RadixPopover.Content
                            className={cn(
                                'z-50 rounded-lg border border-gray-200/60 bg-white p-1 shadow-lg min-w-[100px]',
                                'backdrop-blur-sm animate-in fade-in-0 zoom-in-95',
                                'data-[side=bottom]:slide-in-from-top-2',
                                'data-[side=left]:slide-in-from-right-2',
                                'data-[side=right]:slide-in-from-left-2',
                                'data-[side=top]:slide-in-from-bottom-2'
                            )}
                            side="bottom"
                            align="start"
                            sideOffset={8}
                            collisionPadding={8}
                        >
                            {/* 编辑选项 */}
                            <button
                                onClick={handleEdit}
                                className={cn(
                                    'w-full flex items-center gap-2 px-3 py-2 text-sm text-gray-700',
                                    'hover:bg-gray-100 hover:text-gray-900 rounded-md transition-colors',
                                    'cursor-pointer'
                                )}
                            >
                                <Edit size={14}/>
                                编辑
                            </button>

                            {/* 删除选项 */}
                            <button
                                onClick={handleDelete}
                                className={cn(
                                    'w-full flex items-center gap-2 px-3 py-2 text-sm text-red-600',
                                    'hover:bg-red-50 hover:text-red-700 rounded-md transition-colors',
                                    'cursor-pointer'
                                )}
                            >
                                <Trash2 size={14}/>
                                删除
                            </button>
                        </RadixPopover.Content>
                    </RadixPopover.Portal>
                </RadixPopover.Root>
            </div>
        </div>
    );
};

// 使用 React.memo 优化 SortableSpaceItem 性能，避免拖拽时不必要的重渲染
const SortableSpaceItem = React.memo(
    SortableSpaceItemComponent,
    (prevProps, nextProps) => (
        prevProps.space.id === nextProps.space.id &&
        prevProps.space.name === nextProps.space.name &&
        prevProps.space.icon === nextProps.space.icon &&
        prevProps.space.icon_color === nextProps.space.icon_color &&
        prevProps.space.position === nextProps.space.position &&
        prevProps.isActive === nextProps.isActive
    )
);

/**
 * Spaces列表组件：显示用户的工作空间
 * 功能：空间切换、新建空间、编辑空间、右键菜单操作
 * 支持拖拽排序、活跃状态管理
 */
export const SpacesList = () => {
    const queryClient = useQueryClient();
    const {data: spacesData, isLoading} = useSpaces();
    const deleteSpaceMutation = useDeleteSpace();
    const reorderSpacesMutation = useReorderSpaces();

    // 活跃空间ID（纯UI状态）
    const activeSpaceId = useActiveSpaceStore((state) => state.activeSpaceId);
    const setActiveSpace = useActiveSpaceStore((state) => state.setActiveSpace);

    // 模态框状态
    const [isSpaceModalOpen, setIsSpaceModalOpen] = React.useState(false);
    const [editingSpace, setEditingSpace] = React.useState<Space | undefined>();

    // 删除确认状态
    const [deletingSpace, setDeletingSpace] = React.useState<Space | null>(null);
    const toast = useToast();

    // DragOverlay 状态：记录当前正在拖拽的空间ID
    const [activeId, setActiveId] = React.useState<number | null>(null);

    // 从 Query 缓存中获取并排序空间列表（单一数据源）
    const sortedSpaces = useMemo(() => {
        if (!spacesData) return [];
        return [...spacesData].sort((a, b) => a.position - b.position);
    }, [spacesData]);

    // 自动设置活跃空间（当空间列表加载后且无活跃空间时）
    React.useEffect(() => {
        if (sortedSpaces.length > 0 && !activeSpaceId) {
            setActiveSpace(sortedSpaces[0].id);
        }
    }, [sortedSpaces, activeSpaceId, setActiveSpace]);

    // 使用 useCallback 缓存事件处理函数，避免子组件重渲染
    const handleSpaceClick = useCallback((spaceId: number) => {
        setActiveSpace(spaceId);
        // 失效该空间的 collections 缓存，触发重新获取
        queryClient.invalidateQueries({
            queryKey: QueryKeys.collections(spaceId),
        });
    }, [setActiveSpace, queryClient]);

    // 使用 useCallback 缓存事件处理函数，避免子组件重渲染
    const handleCreateSpace = useCallback(() => {
        setEditingSpace(undefined);
        setIsSpaceModalOpen(true);
    }, []);

    // 使用 useCallback 缓存编辑空间处理函数
    const handleEditSpace = useCallback((space: Space, e: React.MouseEvent) => {
        e.stopPropagation();
        setEditingSpace(space);
        setIsSpaceModalOpen(true);
    }, []);

    // 使用 useCallback 缓存关闭模态框处理函数
    const handleCloseModal = useCallback(() => {
        setIsSpaceModalOpen(false);
        setEditingSpace(undefined);
    }, []);

    // 处理删除空间（显示确认对话框）
    const handleDeleteSpace = useCallback((space: Space) => {
        // 检查是否为最后一个空间
        if (sortedSpaces.length <= 1) {
            toast.error('无法删除最后一个空间，请先创建其他空间');
            return;
        }
        setDeletingSpace(space);
    }, [sortedSpaces.length, toast]);

    // 确认删除空间
    const handleConfirmDelete = useCallback(async () => {
        if (!deletingSpace) return;

        try {
            await deleteSpaceMutation.mutateAsync(deletingSpace.id);
            // 如果删除的是当前活跃空间，切换到第一个可用空间
            if (activeSpaceId === deletingSpace.id) {
                const remainingSpaces = sortedSpaces.filter(s => s.id !== deletingSpace.id);
                if (remainingSpaces.length > 0) {
                    setActiveSpace(remainingSpaces[0].id);
                }
            }
            setDeletingSpace(null);
        } catch (error) {
            console.error('删除空间失败:', error);
        }
    }, [deletingSpace, deleteSpaceMutation, activeSpaceId, sortedSpaces, setActiveSpace]);

    /**
     * 处理拖拽开始事件
     * DragOverlay 模式：记录被拖拽的空间ID，用于渲染 overlay
     */
    const handleDragStart = useCallback((event: DragStartEvent) => {
        setActiveId(event.active.id as number);
    }, []);

    /**
     * 处理拖拽结束事件
     * 关键：先同步更新 Query 缓存，再清除 activeId，避免"回原位再跳新位"
     */
    const handleDragEnd = useCallback((event: DragEndEvent) => {
        const { active, over } = event;

        // 基础校验
        if (!over || active.id === over.id || sortedSpaces.length === 0) {
            setActiveId(null);
            return;
        }

        const ids = sortedSpaces.map((s) => s.id);
        const fromIndex = ids.indexOf(active.id as number);
        const toIndex = ids.indexOf(over.id as number);

        if (fromIndex === -1 || toIndex === -1 || fromIndex === toIndex) {
            setActiveId(null);
            return;
        }

        // 计算拖拽后的新顺序
        const reorderedSpaces = arrayMove(sortedSpaces, fromIndex, toIndex);

        // 计算需要更新的 position
        const updates = calculateDragPositionUpdates(reorderedSpaces, toIndex);

        if (updates.length === 0) {
            setActiveId(null);
            return;
        }

        // ===== 保存原始数据用于失败回滚 =====
        const previousSpaces = [...sortedSpaces];

        // ===== 同步更新缓存（必须在清除 activeId 之前）=====
        const positionMap = new Map(updates.map(u => [u.id, u.position]));

        queryClient.setQueryData<Space[]>(QueryKeys.spaces, (old) => {
            if (!old) return old;

            const updated = old.map(space => {
                const newPosition = positionMap.get(space.id);
                if (newPosition !== undefined && newPosition !== space.position) {
                    return { ...space, position: newPosition };
                }
                return space;
            });

            return updated.sort((a, b) => a.position - b.position);
        });

        // 缓存已同步更新，现在清除 DragOverlay
        setActiveId(null);

        // 构造 API 请求参数并发送（后台同步到服务器）
        const items = updates.map(u => ({ space_id: u.id, position: u.position }));
        reorderSpacesMutation.mutate(
            { items },
            {
                // 失败时使用组件保存的原始数据回滚
                onError: () => {
                    queryClient.setQueryData<Space[]>(QueryKeys.spaces, previousSpaces);
                    toast.error("spaces reorder failed");
                }
            }
        );
    }, [sortedSpaces, reorderSpacesMutation, queryClient]);

    // 获取当前正在拖拽的空间数据（用于 DragOverlay）
    const activeSpace = useMemo(() => {
        return activeId ? sortedSpaces.find(s => s.id === activeId) : null;
    }, [activeId, sortedSpaces]);

    // 加载状态
    if (isLoading) {
        return (
            <div className="spaces-section w-full h-full flex items-center justify-center">
                <span className="text-sm text-gray-400">加载中...</span>
            </div>
        );
    }

    return (
        <>
            <div className="spaces-section w-full h-full flex flex-col min-w-0">
                {/* Spaces 标题头部 - 固定不滚动 */}
                <div
                    className="flex-shrink-0 flex items-center justify-between px-5 py-3 text-2xs font-semibold text-gray-400 tracking-wide w-full min-w-0">
                    <span className="truncate">SPACES</span>
                    {/* 添加Spaces按钮 - 使用统一IconButton组件和Tooltip */}
                    <Tooltip
                        content="新建空间"
                        variant="edit"
                        side="right"
                    >
                        <IconButton
                            onClick={handleCreateSpace}
                            variant="ghost"
                            size="sm"
                            icon={<Plus size={13}/>}
                        />
                    </Tooltip>
                </div>

                {/* 拖拽排序的Spaces列表 - 可滚动区域 */}
                <div className="flex-1 min-h-0">
                    <ScrollContainer
                        className="h-full"
                    >
                        <DndContext
                            collisionDetection={closestCenter}
                            onDragStart={handleDragStart}
                            onDragEnd={handleDragEnd}
                        >
                            <SortableContext
                                items={sortedSpaces.map(s => s.id)}
                                strategy={verticalListSortingStrategy}
                            >
                                <div className="spaces-list">
                                    {sortedSpaces.map((space) => (
                                        <SortableSpaceItem
                                            key={space.id}
                                            space={space}
                                            isActive={space.id === activeSpaceId}
                                            onSpaceClick={handleSpaceClick}
                                            onEditSpace={handleEditSpace}
                                            onDeleteSpace={handleDeleteSpace}
                                        />
                                    ))}
                                </div>
                            </SortableContext>

                            {/* DragOverlay: 拖拽时渲染到独立 Portal，与列表解耦 */}
                            <DragOverlay
                                dropAnimation={{
                                    duration: 50,
                                    easing: 'cubic-bezier(0.18, 0.67, 0.6, 1.22)',
                                }}
                            >
                                {activeSpace ? (
                                    <div className={cn(
                                        // 基础布局
                                        "flex items-center gap-2.5 pl-4 pr-3 py-2 text-sm rounded-xl",
                                        // 背景与边框
                                        "bg-white border border-gray-200",
                                        // 阴影效果（多层阴影增强立体感）
                                        "shadow-[0_8px_24px_rgba(0,0,0,0.12),0_2px_8px_rgba(0,0,0,0.08)]",
                                        // 光标与缩放
                                        "cursor-grabbing scale-105",
                                        // 字体
                                        "text-sm font-medium text-gray-800"
                                    )}>
                                        {/* 拖拽手柄图标 */}
                                        <GripVertical
                                            size={16}
                                            className="flex-shrink-0 text-gray-400"
                                        />

                                        {/* 空间图标 */}
                                        <SpaceIcon
                                            iconId={activeSpace.icon}
                                            size={16}
                                            className="flex-shrink-0"
                                            color={activeSpace.icon_color}
                                        />

                                        {/* 空间名称 */}
                                        <span className="truncate max-w-[180px]">
                                            {activeSpace.name}
                                        </span>
                                    </div>
                                ) : null}
                            </DragOverlay>
                        </DndContext>
                    </ScrollContainer>
                </div>
            </div>

            {/* 空间管理模态框 */}
            <SpaceModal
                space={editingSpace}
                isOpen={isSpaceModalOpen}
                onClose={handleCloseModal}
            />

            {/* 删除确认模态框 */}
            <ConfirmModal
                open={!!deletingSpace}
                onClose={() => setDeletingSpace(null)}
                title="确认删除空间"
                message={`确定要删除空间 "${deletingSpace?.name}" 吗？删除将同时移除其中的所有集合与标签页，且不可撤销。`}
                confirmText="删除空间"
                confirmVariant="danger"
                loading={deleteSpaceMutation.isPending}
                onConfirm={handleConfirmDelete}
            />
        </>
    );
};
